function [hx,hy] = f_tickFormat(hAxes, tickx,ticky, forceLatex, tickposx,tickposy, rotx,roty, offset, varargin)
%F_TICKFORMAT improved TickLabels.
%
%   Replace or appends XTickLabels and YTickLabels of axis handle hAxes
%   with input tickx and ticky array. Adapted from format_tick.m, by Alex
%   Hayes (08/2007)
%
%
% @Requires:        fig [package]
%                   Matlab v2008 onwards
%   
% @Input Parameters:
%
%    	hAxes       Numeric         Handle of axis to change tick labels
%                                   @default: gca
%
%    	tickx       Cellstr{n}      Cell array of XTickLabels to append to
%                                   current labels
%                                   @default: get(hAxes,'XTickLabel');
%
%    	ticky       Cellstr{n}      Cell array of YTickLabels, as per tickx
%                                   @default: get(hAxes,'YTickLabel');
%
%    	forceLatex  Logical         If true then all text is wrapped in
%                                   dollar signs (inline math mode)
%                                   @default: false
%
%    	tickposx    Numeric[n]      Vector of x positions at which to place
%                                   the XTickLabels
%                                   @default: get(hAxes,'XTick')
%
%    	tickposy    Numeric[n]      Vector of y positions, as per tickposx
%                                   @default: get(hAxes,'YTick')
%
%    	rotx        Numeric         Number of degrees to rotate XTickLabels
%                                   @default: 0
%
%    	roty        Numeric         Number of degrees to rotate YTickLabels
%                                   @default: 0
%
%    	offset      Numeric         Label offsets from axis in cm
%                                   @default: 0.2
%
%    	varargin                    Additional parameters for text()
%                                   @default: []
%
% @Returns:  
%
%       hx          Numeric[n]      Handles(s) of text object(s) used as
%                                   XTickLabels
%
%       hy          Numeric[n]      Handles of YTickLabels, as per hx
%
%
% @Syntax:
%
%       [hx,hy] = f_tickFormat([hAxes], [tickx],[ticky], [forceLatex], [tickposx],[tickposy], [rotx],[roty], [offset], [varargin])
%
% @Example:    
%
%       figure(); plot(randn(20),'o');
%       %
%       hAxes = gca;
%       tickx = {'$0$','$2\frac{1}{2}$','$5$','$7\frac{1}{2}$','$10$'};
%       ticky = arrayfun(@(x)sprintf('$%i^{\\circ}$',x),-3:3,'uni',0);
%       forceLatex = false;
%       tickposx = [0,2.5,5,7.5,10];
%       tickposy = -3:3;
%       rotx = 0;
%       roty = 45;
%       offset = [];
%       varargin = {'FontWeight','Bold'};
%       f_tickFormat(hAxes, tickx,ticky, forceLatex, tickposx,tickposy, rotx,roty, offset, varargin{:})
%
% @See also:        fig_axesFormat.m
% 
% @Author:          Pete R Jones <petejonze@gmail.com>
%
% @Version History: 1.0.0	11/10/12	First Build            	[PJ]
%                   1.0.1	08/10/12	Tweaks & comments       [PJ]
%
% @Todo:            <none>

adjustAxesToFitRange = false;

% %define axis text offset (percentage of total range)
% if ~exist('offset','var') || isempty(offset)
%     offset = 0.02;
% end;
%define axis text offset (cm)
if ~exist('offset','var') || isempty(offset)
    xTickLbl_offset = .2; % cm
    yTickLbl_offset = .2; % cm
else
   xTickLbl_offset = offset;
   yTickLbl_offset = offset;
end
% xTickLbl_offset_norm = getUnits(h,xTickLbl_offset,'centimeters');
% yTickLbl_offset_norm = getUnits(h,yTickLbl_offset,'centimeters');
xTickLbl_offset_dat = getUnits(hAxes,xTickLbl_offset,'centimeters','data',1); % text is set to Data units by default. Dim is 1 because we are arranging the VERTICAL position of the xAxis ticks!
yTickLbl_offset_dat = getUnits(hAxes,yTickLbl_offset,'centimeters','data',2);

if nargin<4 || isempty(forceLatex)
    forceLatex = false;
end
 
%make sure the axis handle input really exists
if ~exist('hAxes','var');
    h = gca;
    warning('f_tickFormat:bad_input',['Axis handle NOT Input, Defaulting to Current Axes, '...
        num2str(hAxes)]);
elseif isempty(hAxes);
    h = gca;
    warning('f_tickFormat:bad_input',['Axis Handle NOT Input, Defaulting to Current Axes, '...
        num2str(hAxes)]);
elseif ~ishandle(hAxes(1))
    warning('f_tickFormat:bad_input',['Input (' num2str(hAxes(1)) ') is NOT an axis handle, ' ...
        'defaulting to current axis, ' num2str(h)]);
        hAxes = gca;
end;

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%BEGIN: FIRST THE X-AXIS TICK LABELS
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%fix the XTickLabels if they have been erased in the past
% no - now just skips if xlabel is blank
if isempty((get(hAxes,'XTickLabel')))
    % set(h,'XTickLabel',get(h,'XTick'));
    hx = [];
else
    % set the xtick positions if entered
    if exist('tickposx','var')
        if ~isempty(tickposx);
            set(hAxes,'XTick',tickposx);
        end;
        tickposx = get(hAxes,'XTick');
        set(hAxes,'XTickLabel',tickposx);
    end;
    %make sure the xtick positions are in the xlimit range
    if exist('tickposx','var');
        if ~isempty(tickposx);
            lim = get(hAxes,'XLim');
            if lim(1) > min(tickposx);
                if adjustAxesToFitRange
                    lim(1) = min(tickposx);
             	else
                    tickposx(tickposx<lim(1)) = NaN;
                end
            end;
            if lim(2) < max(tickposx);
                if adjustAxesToFitRange
                    lim(2) = max(tickposx);
                else
                    tickposx(tickposx>lim(2)) = NaN;
                end
            end;
            set(hAxes,'XLim',lim);
        end;
    end;
    %get the tick labels and positions if the user did not input them
    if ~exist('tickx','var');
        tickx = get(hAxes,'XTickLabel');
        if ischar(tickx);
            temp = tickx;
            tickx = cell(1,size(temp,1));
            for j=1:size(temp,1);
                tickx{j} = strtrim( temp(j,:) );
            end;
        end;
        append = '^{\circ}';
        for j=1:length(tickx);
            tickx{j} = [tickx{j} append];
        end;
    elseif isempty(tickx);
        tickx = get(hAxes,'XTickLabel');
        if ischar(tickx);
            temp = tickx;
            tickx = cell(1,size(temp,1));
            for j=1:size(temp,1);
                tickx{j} = strtrim( temp(j,:) );
            end;
        end;
        append = '^{\circ}';
        for j=1:length(tickx);
            tickx{j} = [tickx{j} append];
        end;
    elseif ischar(tickx);
        append = tickx;
        tickx = get(hAxes,'XTickLabel');
        if ischar(tickx);
            temp = tickx;
            tickx = cell(1,size(temp,1));
            for j=1:size(temp,1);
                tickx{j} = strtrim( temp(j,:) );
            end;
        end;
        if strcmp(append(1),'$');
            for j=1:length(tickx);
                tickx{j} = ['$' tickx{j} append(2:end)];
            end;
        else          
            for j=1:length(tickx);
                tickx{j} = [tickx{j} append];
            end;
        end;
    elseif ~iscell(tickx );
        warning('f_tickFormat:bad_input',['Input TICKX variable is not a compatible string ' ...
            'or cell array! Returning...']);
        return;
    elseif iscell(tickx) && length(tickx)==1 && ischar(tickx{1}) %pj
        tickx = cellstr(tickx{1})';
    end
    %find out if we have to use the LaTex interpreter
    if ~forceLatex
        temp = tickx{1};
        if strcmp(temp(1),'$');
            latex_on = 1;
        else
            latex_on = 0;
        end;
    else
        tickx = cellfun(@(x)['$' x '$'], tickx,'UniformOutput',false);
        latex_on = 1;
    end
    %erase the current tick label
    set(hAxes,'XTickLabel',{});
    %get the x tick positions if the user did not input them
    if ~exist('tickposx','var');
        tickposx = get(hAxes,'XTick');
    elseif isempty(tickx);
        tickposx = get(hAxes,'XTick');
    end;
    %get the y tick positions if the user did not input them
    if ~exist('tickposy','var');
        tickposy = get(hAxes,'YTick');
    elseif isempty(tickposy);
        tickposy = get(hAxes,'YTick');
    end;
    %set the new tick positions
    set(hAxes,'YTick',tickposy);
    set(hAxes,'XTick',tickposx);
    %check the lengths of the xtick positions and xtick labels
    l1 = length(tickx);
    l2 = length(tickposx);
    if l1==0; 
        set(hAxes,'XTickLabel',tickx);
    end;
    if l1~=l2;
        disp(['Length of XTick = ' num2str(length(tickposx))]);
        disp(['Length of XTickLabel = ' num2str(length(tickx))]);
        if l2 < l1;
            warning('f_tickFormat:bad_input','Reducing Length of XTickLabel!');
        else
            warning('f_tickFormat:bad_input','Reducing Length of XTick!');
        end;   
        l3 = min([l1,l2]);
        tickx = tickx(1:l3);
        tickposx = tickposx(1:l3);
    end;
    %set rotation to 0 if not input
    if ~exist('rotx','var');
        rotx = 0;
    elseif isempty(rotx); 
        rotx = 0;
    end;
    %Convert the cell labels to a character string
    %tickx = char(tickx);
    tickx = cellstr(tickx);
    %Make the XTICKS!
    lim = get(hAxes,'YLim');
    
    if adjustAxesToFitRange
        if min(tickposy) < lim(1);
            lim(1) = min(tickposy);
        end;
        if max(tickposy) > lim(2);
            lim(2) = max(tickposy);
        end;
    end

    
    if rotx == 0;
        hAlign = 'center';
        vAlign = 'top';
    elseif rotx < 0;
        hAlign = 'left';
        vAlign = 'middle';   
    else
        hAlign = 'right';
        vAlign = 'middle';      
    end
    %
    if latex_on;
        interp = 'LaTex';
    else
        interp = 'Tex';
    end
    
    % PLOT----------------------------------
    if strcmp(get(gca,'YScale'), 'log') % reintroduced to get corrmatrix working
        yposition = 10^(log10(lim(1)) - xTickLbl_offset_dat);
    else
        yposition = lim(1) - xTickLbl_offset_dat; % shift xTicks down
    end 
    hx = text(tickposx,...
        repmat(yposition,length(tickposx),1),...
        tickx,'HorizontalAlignment',hAlign,...
        'VerticalAlignment',vAlign,'rotation',rotx,'interpreter',interp,'tag','xTickLabel'); % useful when debugging: ,'BackgroundColor',[.7 .9 .7]);
    % PLOT----------------------------------
    
    %Get and set the text size and weight
    set(hx,'FontSize',get(hAxes,'FontSize'));
    set(hx,'FontWeight',get(hAxes,'FontWeight'));

    %Set the additional parameters if they were input
    if length(varargin) > 2;
        command_string = 'set(hx';
        for j=1:2:length(varargin);
            command_string = [command_string ',' ...
                '''' varargin{j} ''',varargin{' num2str(j+1) '}']; %#ok
        end;
        command_string = [command_string ');'];
        eval(command_string);
    end;
end
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%END: FIRST THE X-AXIS TICK LABELS
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%     

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%BEGIN: NOW THE Y-AXIS TICK LABELS
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%only move forward if we are doing anything to the yticks
if ~exist('ticky','var') || isempty(ticky) || isempty((get(hAxes,'YTickLabel')))
    hy = []; % empty is better than -1, since less likely throw invalid handle exceptions
else
    %fix the YTickLabels if they have been erased in the past
    if isempty(get(hAxes,'YTickLabel'));
        set(hAxes,'YTickLabel',get(hAxes,'YTick'));
    end;
    %set the ytick positions if entered
    if exist('tickposy','var');
        if ~isempty(tickposy);
            set(hAxes,'YTick',tickposy);
            set(hAxes,'YTickLabel',tickposy);
        end;
    end;
    %make sure the ytick positions are in the ylimit range
    if exist('tickposy','var');
        if ~isempty(tickposy);
            lim = get(hAxes,'YLim');
            if lim(1) > min(tickposy);
                if adjustAxesToFitRange
                    lim(1) = min(tickposy);
                else
                    tickposy(tickposy<lim(1)) = NaN;
                end
            end;
            if lim(2) < max(tickposy);
                if adjustAxesToFitRange
                    lim(2) = max(tickposy);
                else
                    tickposy(tickposy>lim(2)) = NaN;
                end
            end;
            set(hAxes,'YLim',lim);
        end;
    end;
    
    %get the tick labels and positions if the user did not input them
    if ~exist('ticky','var');
        ticky = get(hAxes,'YTickLabel');
        if ischar(ticky);
            temp = ticky;
            ticky = cell(1,size(temp,1));
            for j=1:size(temp,1);
                ticky{j} = strtrim( temp(j,:) );
            end;
        end;
        append = '^{\circ}';
        for j=1:length(ticky);
            ticky{j} = [ticky{j} append];
        end;
    elseif isempty(ticky);
        ticky = get(hAxes,'YTickLabel');
        if ischar(ticky);
            temp = ticky;
            ticky = cell(1,size(temp,1));
            for j=1:size(temp,1);
                ticky{j} = strtrim( temp(j,:) );
            end;
        end;
        append = '^{\circ}';
        for j=1:length(ticky);
            ticky{j} = [ticky{j} append];
        end;
    elseif ischar(ticky);
        append = ticky;
        ticky = get(hAxes,'YTickLabel');
        if ischar(ticky);
            temp = ticky;
            ticky = cell(1,size(temp,1));
            for j=1:size(temp,1);
                ticky{j} = strtrim( temp(j,:) );
            end;
        end;
        if strcmp(append(1),'$');
            for j=1:length(ticky);
                ticky{j} = ['$' ticky{j} append(2:end)];
            end;
        else
            for j=1:length(ticky);
                ticky{j} = [ticky{j} append];
            end;
        end;
    elseif ~iscell(ticky );
        warning('f_tickFormat:bad_input',['Input TICKY variable is not a compatible string ' ...
            'or cell array! Returning...']);
        return;
    elseif iscell(ticky) && length(ticky)==1 && ischar(ticky{1}) %pj
        ticky = cellstr(ticky{1})';
    end
    
    %find out if we have to use the LaTex interpreter
    if ~forceLatex
        temp = ticky{1};
        if strcmp(temp(1),'$');
            latex_on = 1;
        else
            latex_on = 0;
        end;
    else
        ticky = cellfun(@(x)['$' x '$'], ticky,'UniformOutput',false);
        latex_on = 1;
    end
    %erase the current tick label
    set(hAxes,'YTickLabel',{});
    %get the y tick positions if the user did not input them
    if ~exist('tickposy','var') || isempty(tickposy);
        tickposy = get(hAxes,'YTick');
    elseif isempty(ticky);
        tickposy = get(hAxes,'YTick');
    end;
    
    %get the x tick positions if the user did not input them
    if ~exist('tickposx','var');
        tickposx = get(hAxes,'YTick');
    elseif isempty(tickposx);
        tickposx = get(hAxes,'XTick');
    end;
    %set the new tick positions
    set(hAxes,'YTick',tickposy);
%    set(hAxes,'XTick',tickposx);
    %check the lengths of the xtick positions and xtick labels
    l1 = length(ticky);
    l2 = length(tickposy);
    if l1==0;
        set(hAxes,'YTickLabel',ticky);
    end;
    if l1~=l2;
        disp(['Length of YTick = ' num2str(length(tickposy))]);
        disp(['Length of YTickLabel = ' num2str(length(ticky))]);
        if l2 < l1;
            warning('f_tickFormat:bad_input','Reducing Length of YTickLabel!');
        else
            warning('f_tickFormat:bad_input','Reducing Length of YTick!');
        end;
        l3 = min([l1,l2]);
        ticky = ticky(1:l3);
        tickposy = tickposy(1:l3);
    end;
    %set rotation to 0 if not input
    if ~exist('roty','var');
        roty = 0;
    elseif isempty(roty);
        roty = 0;
    end;
    %Convert the cell labels to a character string
    %ticky = char(ticky);
    ticky = cellstr(ticky);
    %Make the YTICKS!
    lim = get(hAxes,'XLim');
    if min(tickposx) < lim(1);
        lim(1) = min(tickposx);
    end;
    if max(tickposx) > lim(2);
        lim(2) = max(tickposx);
    end;
    
    
    
    if roty == 0;
        hAlign = 'right';
        vAlign = 'middle';
    elseif roty < 0;
        hAlign = 'right';
        vAlign = 'middle';
    else
        hAlign = 'right';
        vAlign = 'middle';
    end
    %
    if latex_on;
        interp = 'LaTex';
    else
        interp = 'Tex';
    end
    
    % PLOT----------------------------------
    ticky = ticky';
    if strcmp(get(gca,'XScale'), 'log') % reintroduced to get corrmatrix working
        xposition = 10^(log10(lim(1)) - yTickLbl_offset_dat);
    else
        xposition = lim(1) - yTickLbl_offset_dat; % nudge y axis ticklabels (negative => left)
    end

    hy = text(...
        repmat(xposition,length(tickposy),1),...
        tickposy,...
        ticky,'VerticalAlignment',vAlign,...
        'HorizontalAlignment',hAlign,'rotation',roty,'interpreter',interp,'tag','yTickLabel'); % useful when debugging: ,'BackgroundColor',[.7 .9 .7]);
    % PLOT----------------------------------

    
    %Get and set the text size and weight
    set(hy,'FontSize',get(hAxes,'FontSize'));
    set(hy,'FontWeight',get(hAxes,'FontWeight'));

    %Set the additional parameters if they were input
    if length(varargin) > 2;
        command_string = 'set(hy';
        for j=1:2:length(varargin);
            command_string = [command_string ',' ...
                '''' varargin{j} ''',varargin{' num2str(j+1) '}']; %#ok
        end;
        command_string = [command_string ');'];
        eval(command_string);
    end;
end;